package com.example.demo.filters;

import org.springframework.web.filter.OncePerRequestFilter;
import org.springframework.web.util.ContentCachingRequestWrapper;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;

@WebFilter("/api/*")
public class RequestLogFilter extends OncePerRequestFilter {
    private static final Logger log = Logger.getLogger(RequestLogFilter.class.getName());

    @Override
    protected void doFilterInternal(HttpServletRequest request,
                                    HttpServletResponse response,
                                    FilterChain filterChain) throws IOException, ServletException {

        // 使用ContentCachingRequestWrapper包装请求以便重复读取body
        ContentCachingRequestWrapper wrappedRequest = new ContentCachingRequestWrapper(request);

        // 记录请求开始时间
        long startTime = System.currentTimeMillis();

        try {
            // 继续过滤器链
            filterChain.doFilter(wrappedRequest, response);
        } finally {
            // 只记录JSON请求的body
            if (wrappedRequest.getContentType() != null &&
                    wrappedRequest.getContentType().contains("application/json")) {

                // 获取缓存的请求体内容
                byte[] content = wrappedRequest.getContentAsByteArray();
                String requestBody = content.length > 0 ?
                        new String(content, wrappedRequest.getCharacterEncoding()) : "{}";

                // 计算请求耗时
                long duration = System.currentTimeMillis() - startTime;

                // 记录请求信息
                log.log(Level.INFO,
                        "API Request - Method: {0}\nPath: {1}\nDuration: {2}ms\nBody: {3}",
                        new Object[]{
                                wrappedRequest.getMethod(),
                                wrappedRequest.getRequestURI(),
                                duration,
                                requestBody
                        });
            }
        }
    }

    @Override
    protected boolean shouldNotFilter(HttpServletRequest request) {
        // 排除一些不需要记录的路径
        String path = request.getRequestURI();
        return path.startsWith("/api/auth/") ||
                path.startsWith("/swagger-ui/") ||
                path.startsWith("/v3/api-docs/");
    }
}